#include <string>

using namespace std;

class Screen {
    public:
        typedef string::size_type pos;
        char get_cursor() const { return contents[cursor]; }
        char get() const { return contents[0]; }
        char get(pos ht, pos wd) const { return contents[max(ht, wd)]; }
        // data 是一个静态成员，返回一个成员指针
        static const string Screen::*data()
            { return &Screen::contents; }
    private:
        string contents;
        pos cursor;
        pos height, width;
};

namespace {
    // 使用类型别名，让含有成员指针的代码更易读
    using Action = char (Screen::*)(Screen::pos, Screen::pos) const;
    Action get = &Screen::get; // get 指向 Screen 的 get 成员
    // action 接受一个 Screen 的引用，和一个指向 Screen 成员函数的指针
    Screen& action(Screen& s, Action a = &Screen::get)
        { (s.*a)(0, 1); return s; }
}

int main()
{
    // 函数成员指针，要指定目标函数的返回类型和形参列表
    auto pmf = &Screen::get_cursor;

    // pmf2 指向 char get(pos ht, pos wd) const
    char (Screen::*pmf2)(Screen::pos, Screen::pos) const;
    pmf2 = &Screen::get;

    // pmf3 指向 char get() const
    char (Screen::*pmf3)() const;
    pmf3 = &Screen::get;

    // 错误：非成员函数 p 不能使用 const 限定符
    // char Screen::*p(Screen::pos, Screen::pos) const;

    Screen myScreen, *pScreen = &myScreen;
    // 通过 pScreen 所指的对象调用 pmf 所指的函数
    char c1 = (pScreen->*pmf)();
    // 通过 myScreen 对象将实参 0, 0 传给含有两个形参的 get 函数
    char c2 = (myScreen.*pmf2)(0, 0);

    action(myScreen);                   // 使用默认实参
    // action(myScreen, get);           // 使用之前定义的变量 get
    action(myScreen, &Screen::get);     // 显式地传入地址
}